package com.features;

import java.net.InetAddress;
import java.net.UnknownHostException;

import org.hyperic.sigar.NetFlags;
import org.hyperic.sigar.NetInterfaceConfig;
import org.hyperic.sigar.NetInterfaceStat;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;
import org.hyperic.sigar.SigarNotImplementedException;
import org.safehaus.uuid.EthernetAddress;
import org.safehaus.uuid.UUIDGenerator;

import com.utils.AbstractTrace;

/** <p>Title: 网络信息</p>
 * <p>Description: 获取系统网络信息</p>
 * <p>Copyright: Copyright (c) 2011</p>
 * @author zhangzuoqiang
 * @version 
 * <br/>Date: 2011-5-10
 */
public class NetCommand extends AbstractTrace {
	
	/**
	 * 当前机器的正式域名
	 * @return
	 */
	public String getFQDN(){
		try {
			return InetAddress.getLocalHost().getCanonicalHostName();
		} catch (UnknownHostException e) {
			Sigar sigar = null;
			try {
				sigar = new Sigar();
				return sigar.getFQDN();
			} catch (SigarException ex) {
				return null;
			} finally {
				sigar.close();
			}
		}
	}
	
	/**
	 * 取到当前机器的IP地址
	 * @return
	 */
	public String getDefaultIpAddress() {
		String address = null;
		try {
			address = InetAddress.getLocalHost().getHostAddress();
			// 没有出现异常而正常当取到的IP时，如果取到的不是网卡循回地址时就返回
			// 否则再通过Sigar工具包中的方法来获取
			if (!NetFlags.LOOPBACK_ADDRESS.equals(address)) {
				return address;
			}
		} catch (UnknownHostException e) {
			//hostname not in DNS or /etc/hosts
		}
		Sigar sigar = new Sigar();
        try {
        	address = sigar.getNetInterfaceConfig().getAddress();
        } catch (SigarException e) {
        	address = NetFlags.LOOPBACK_ADDRESS;
        } finally {
            sigar.close();
        }
        return address;
	}
	
	/**
	 * 取到当前机器的MAC地址列表
	 * @return
	 */
	public String[] getMACList() {
		Sigar sigar = null;
		try {
			sigar = new Sigar();
            String[] ifaces = sigar.getNetInterfaceList();
            String[] hwaddr = new String[ifaces.length];
        	/* 
        	 * 如果存在多张网卡包括虚拟机的网卡，并且要返回所有的网卡
        	 * （包括物理的和虚拟的）则可以修改方法的返回类型为数组或
        	 * Collection，通过在for循环里取到的多个MAC地址。
        	 */
            for (int i = 0; i < ifaces.length; i++) {
            	NetInterfaceConfig cfg = sigar.getNetInterfaceConfig(ifaces[i]);
            	if (NetFlags.LOOPBACK_ADDRESS.equals(cfg.getAddress())
            			|| (cfg.getFlags() & NetFlags.IFF_LOOPBACK) != 0
            			|| NetFlags.NULL_HWADDR.equals(cfg.getHwaddr())) {
            		continue;
            	}
            	hwaddr[i] = cfg.getHwaddr();
            	//break;
            }
            return hwaddr;
		} catch (Exception e) {
			return null;
		} finally {
			if (sigar != null)
				sigar.close();
		}
	}
	
	/**
	 * 根据MAC地址来获得一个GUID号
	 * @param mac
	 * @return
	 */
	public String getGUID(String mac) {
		if (mac == null)
			return null;
		EthernetAddress eAddr = new EthernetAddress(mac);
		return UUIDGenerator.getInstance().generateTimeBasedUUID(eAddr).toString();
	}
	
	/**
	 * 获取网络流量等信息
	 */
	public void getNetIfList() {
		Sigar sigar = new Sigar();
        String ifNames[] = null;
		try {
			ifNames = sigar.getNetInterfaceList();
		} catch (SigarException e1) {
			e1.printStackTrace();
		}
        for (int i = 0; i < ifNames.length; i++) {
        	String name = ifNames[i];
            NetInterfaceConfig ifconfig = null;
			try {
				ifconfig = sigar.getNetInterfaceConfig(name);
			} catch (SigarException e1) {
				e1.printStackTrace();
			}
            traceln("\nname = " + name);//网络设备名
            traceln("Address = "+ ifconfig.getAddress());//IP地址
            traceln("Netmask = "+ ifconfig.getNetmask());//子网掩码
            if ( (ifconfig.getFlags() & 1L) <= 0L) {
            	traceln("!IFF_UP...skipping getNetInterfaceStat");
            	continue;
            }
            
            try {
            	NetInterfaceStat ifstat = sigar.getNetInterfaceStat(name);
            	traceln("RxPackets = " + ifstat.getRxPackets());//接收的总包裹数
            	traceln("TxPackets = " + ifstat.getTxPackets());//发送的总包裹数
            	traceln("RxBytes = " + ifstat.getRxBytes());//接收到的总字节数
            	traceln("TxBytes = " + ifstat.getTxBytes());//发送的总字节数
            	traceln("RxErrors = " + ifstat.getRxErrors());//接收到的错误包数
            	traceln("TxErrors = " + ifstat.getTxErrors());//发送数据包时的错误数
            	traceln("RxDropped = " + ifstat.getRxDropped());//接收时丢弃的包数
            	traceln("TxDropped = " + ifstat.getTxDropped());//发送时丢弃的包数
            } catch (SigarNotImplementedException e) {
            	
            } catch (SigarException e) {
            	traceln(e.getMessage());
            }
        }
	}
	
	/**
	 * 一些其他的信息
	 */
	public void getEthernetInfo(){
		Sigar sigar = null;
        try {
        	sigar = new Sigar();
            String[] ifaces = sigar.getNetInterfaceList();
            for (int i = 0; i < ifaces.length; i++) {
            	NetInterfaceConfig cfg = sigar.getNetInterfaceConfig(ifaces[i]);
            	if (NetFlags.LOOPBACK_ADDRESS.equals(cfg.getAddress())
            			|| (cfg.getFlags() & NetFlags.IFF_LOOPBACK) != 0
            			|| NetFlags.NULL_HWADDR.equals(cfg.getHwaddr())) {
            		continue;
            	}
            	traceln("cfg.getAddress() = " + cfg.getAddress());//IP地址
            	traceln("cfg.getBroadcast() = " + cfg.getBroadcast());//网关广播地址
            	traceln("cfg.getHwaddr() = " + cfg.getHwaddr());//网卡MAC地址
            	traceln("cfg.getNetmask() = " + cfg.getNetmask());//子网掩码
            	traceln("cfg.getDescription() = " + cfg.getDescription());//网卡描述信息
            	traceln("cfg.getType() = " + cfg.getType());//
            	traceln("cfg.getDestination() = " + cfg.getDestination());
            	traceln("cfg.getFlags() = " + cfg.getFlags());//
            	traceln("cfg.getMetric() = " + cfg.getMetric());
            	traceln("cfg.getMtu() = " + cfg.getMtu());
            	traceln("cfg.getName() = " + cfg.getName());
            	traceln();
            }
        } catch (Exception e) {
        	traceln("Error while creating GUID" + e);
        } finally {
        	if (sigar != null)
        		sigar.close();
        }
	}
	
}